/**
 * 
 */
package backend;

import gui.controller.MenuController;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;

import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import main.Ausruestungsstart;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * @author Christian
 * 
 */
public class DatenController {
	
	private static DatenController self;
	
	private HashMap<String, ArrayList<String>> itemMap = new HashMap<String, ArrayList<String>>();
	
	private File file;
	
	private DatenController() {

		file = new File(this.getClass().getProtectionDomain().getCodeSource().getLocation()
				.getPath());
		file = file.getParentFile();
		file = new File(file.getAbsolutePath() + "/ausruestungs.xml");
		laden();
	}
	
	public static DatenController getInstance() {

		if (self == null) {
			self = new DatenController();
		}
		return self;
	}
	
	public void setKlassenItemList(String klassenName, ArrayList<String> list) {

		itemMap.put(klassenName, list);
	}
	
	public ArrayList<String> getKlassenItemList(String name) {

		return itemMap.get(name);
	}
	
	/**
	 * @param selectedItem
	 */
	public void entferneItemSet(String selectedItem) {

		itemMap.remove(selectedItem);
	}
	
	public ArrayList<String> getAlleSetNamen() {

		ArrayList<String> list = new ArrayList<String>();
		for (String s : itemMap.keySet()) {
			list.add(s);
		}
		Collections.sort(list);
		return list;
	}
	
	public boolean isNameInBenutzung(String name) {

		return itemMap.containsKey(name);
	}
	
	/**
	 * 
	 */
	public void speichern() {

		inXMLSpeichern();
		// JOptionPane.showMessageDialog(null, "Es wurde erfolgreich gespeichert!", "Erfolg",
		// JOptionPane.WARNING_MESSAGE);
	}
	
	public void laden() {

		if (!versionCheck()) {
			JOptionPane.showMessageDialog(null, "Es wurden alte XML-Files gefunden \n"
					+ "Es wird jetzt versucht diese zu Laden, dabei kann es zu Fehlern kommen.",
					"Achtung", JOptionPane.WARNING_MESSAGE);
		}
		ausXMLLaden();
	}
	
	private void inXMLSpeichern() {

		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		Document document;
		try {
			document = factory.newDocumentBuilder().newDocument();
			Element topElement = document.createElement("Ausruestung");
			document.appendChild(topElement);
			Element versionBereich = document.createElement("Version");
			versionBereich.setAttribute("XMLVersion", Ausruestungsstart.getXMLVersion());
			topElement.appendChild(versionBereich);
			Element itemSets = document.createElement("ItemSets");
			topElement.appendChild(itemSets);
			for (String setName : itemMap.keySet()) {
				Element itemSet = document.createElement("ItemSet");
				itemSet.setAttribute("name", setName);
				itemSets.appendChild(itemSet);
				for (String s : itemMap.get(setName)) {
					Element itemElement = document.createElement("item");
					itemElement.setAttribute("name", s);
					itemSet.appendChild(itemElement);
				}
			}
			// jetzt noch in einen Datei Transformieren.
			TransformerFactory tFactory = TransformerFactory.newInstance();
			Transformer transformer = tFactory.newTransformer();
			transformer.setOutputProperty(OutputKeys.INDENT, "yes");
			transformer.setOutputProperty(OutputKeys.STANDALONE, "yes");
			transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
			DOMSource source = new DOMSource(document);
			StreamResult result = new StreamResult(file);
			transformer.transform(source, result);
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (TransformerException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 
	 */
	private void ausXMLLaden() {

		xmlEinlesen(file, false);
	}
	
	/**
	 * @return
	 * 
	 */
	public void importFromXML() {

		JFileChooser chooser = new JFileChooser();
		chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
		chooser.setMultiSelectionEnabled(false);
		int erg = chooser.showOpenDialog(null);
		if (erg == JFileChooser.CANCEL_OPTION) {
			return;
		}
		if (erg != JFileChooser.CANCEL_OPTION && erg != JFileChooser.ERROR_OPTION) {
			if (isAusruestungsXML(chooser.getSelectedFile())) {
				if (!versionCheck(chooser.getSelectedFile())) {
					String fehlertext = "Es wurde ein altes XML-File erkannt\n"
							+ "Es wird jetzt versucht dieses zu laden, dabei kann es zu Fehlern kommen.";
					JOptionPane.showMessageDialog(null, fehlertext, "Achtung",
							JOptionPane.WARNING_MESSAGE);
				}
				if (xmlEinlesen(chooser.getSelectedFile(), true)) {
					JOptionPane.showMessageDialog(null, "Datei wurde importiert!",
							"Ausrüstungsplugin", JOptionPane.INFORMATION_MESSAGE);
					return;
				}
			} else {
				JOptionPane.showMessageDialog(null,
						"Es handelt sich nicht um ein AusrüstungsXML!", "Ausrüstungsplugin",
						JOptionPane.ERROR_MESSAGE);
				return;
			}
		}
		JOptionPane.showMessageDialog(null, "Beim Importieren ist ein Fehler aufgetretten!",
				"Ausrüstungsplugin", JOptionPane.ERROR_MESSAGE);
	}
	
	private boolean xmlEinlesen(File file, boolean importieren) {

		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		Document document;
		boolean importOk = false;
		try {
			DocumentBuilder builder = factory.newDocumentBuilder();
			document = builder.parse(file);
			// ItemSets
			NodeList itemSets = document.getElementsByTagName("ItemSet");
			for (int i = 0; itemSets != null && i < itemSets.getLength(); i++) {
				Node n = itemSets.item(i);
				String name = n.getAttributes().getNamedItem("name").getNodeValue();
				ArrayList<String> list = new ArrayList<String>();
				NodeList setItems = n.getChildNodes();
				for (int i2 = 0; i2 < setItems.getLength(); i2++) {
					Node setItemNode = setItems.item(i2);
					if (setItemNode != null && setItemNode.getNodeName().equals("item")) {
						list.add(setItemNode.getAttributes().getNamedItem("name").getNodeValue());
					}
				}
				if (!importieren) {
					itemMap.put(name, list);
					importOk = true;
				} else {
					int j = 1;
					String name2 = name;
					while (isNameInBenutzung(name2)) {
						name2 = name + j;
						j++;
					}
					itemMap.put(name2, list);
					importOk = true;
				}
			}
		} catch (FileNotFoundException e) {
			return false;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return importOk;
	}
	
	public boolean versionCheck() {

		return versionCheck(file);
	}
	
	/**
	 * Gibt true bei geleicher xml version oder bei wenn das File nicht existiert zurück
	 * 
	 * @return
	 */
	private boolean versionCheck(File file) {

		if (file.exists()) {
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			Document document;
			try {
				DocumentBuilder builder = factory.newDocumentBuilder();
				document = builder.parse(file);
				NodeList versionsNode = document.getElementsByTagName("Version");
				for (int i = 0; i < versionsNode.getLength(); ) {
					Node n = versionsNode.item(i);
					String version = n.getAttributes().getNamedItem("XMLVersion").getNodeValue();
					return Ausruestungsstart.getXMLVersion().equals(version);
				}
			} catch (FileNotFoundException e) {
				System.out.println("Datei nicht gefunden");
			} catch (Exception e) {
				e.printStackTrace();
				return false;
			}
			return false;
		}
		new MenuController().zeigeInfo();
		return true; // wenn file nicht existiert
	}
	
	public static boolean isAusruestungsXML(File file) {

		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		Document document;
		try {
			DocumentBuilder builder = factory.newDocumentBuilder();
			document = builder.parse(file);
			NodeList versionsNode = document.getElementsByTagName("Ausruestung");
			return versionsNode.getLength() > 0;
		} catch (FileNotFoundException e) {
			System.out.println("Datei nicht gefunden");
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		return false;
	}
//	public static void main(String[] args) {
//
//		File file = new File("C:\\Users\\Christian\\plugins\\zauberinfo.xml");
//		System.out.println(isAusruestungsXML(file));
//	}
}
